package com.eudon.genius.api.core.parser.component;

import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 包扫描器
 * 负责根据包名或源码路径扫描Java文件
 *
 * @author eudon
 * @since 2025/9/25
 */
@Slf4j
public class PackageScanner {

    /**
     * 扫描指定包名下的所有Java文件
     *
     * @param packageName 包名 (如: com.example.controller)
     * @param sourcePath  源码根路径列表
     * @return Java文件路径列表
     */
    public List<Path> scanPackage(String packageName, Path sourcePath) {
        List<Path> javaFiles = new ArrayList<>();

        // 将包名转换为路径
        String packagePath = packageName.replace('.', '/');

        Path packageDir = sourcePath.resolve(packagePath);

        if (Files.exists(packageDir) && Files.isDirectory(packageDir)) {
            log.debug("扫描包目录: {}", packageDir);
            javaFiles.addAll(scanDirectory(packageDir, true));
        } else {
            log.debug("包目录不存在: {}", packageDir);
        }


        log.info("包 {} 下找到 {} 个Java文件", packageName, javaFiles.size());
        return javaFiles;
    }

    /**
     * 递归扫描目录下的所有Java文件
     *
     * @param directory 要扫描的目录
     * @param recursive 是否递归扫描子目录
     * @return Java文件路径列表
     */
    private List<Path> scanDirectory(Path directory, boolean recursive) {
        List<Path> javaFiles = new ArrayList<>();

        try (Stream<Path> paths = Files.walk(directory, recursive ? Integer.MAX_VALUE : 1)) {
            javaFiles = paths
                    .filter(Files::isRegularFile)
                    .filter(this::isJavaFile)
                    .collect(Collectors.toList());

        } catch (IOException e) {
            log.error("扫描目录失败: {}", directory, e);
        }

        return javaFiles;
    }

    /**
     * 判断是否为Java文件
     *
     * @param path 文件路径
     * @return 是否为Java文件
     */
    private boolean isJavaFile(Path path) {
        return path.toString().toLowerCase().endsWith(".java");
    }
}